﻿using Konveyer.Core;
using Konveyer.Core.Attributes;
using Konveyer.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Konveyer.Example
{
    public static class ExampleThree
    {
        public static void Go()
        { 
            // all this is athe same as Example one 
            // get an instance provider and tell it about our widgets . Note the order is not important  
            var instanceProvider = Factory.GetInstanceProvider() ;
            instanceProvider.Register<ExampleThreeWidget_2>(typeof(ExampleThreeWidget_2));
            instanceProvider.Register<ExampleThreeWidget_1>(typeof(ExampleThreeWidget_1));

            // Get a Runner 
            var runner = Factory.GetRunner(instanceProvider);

            // make a request to carry our data in and out 
            var request = new ExampleThreeRequest();
            request.Name = "dave" ; 

            // execute a request
            runner.Execute(request) ;

            // view the result 
            Console.WriteLine("Result (Example 3): " + request.Greeting);

            // view the errors
            Console.WriteLine("Errors (Example 3)");
            var errors = request.Exception as WidgetValidationException ;
            if(errors != null)
            {
                errors.ErrorMessages.ToList().ForEach(err => {  
                    Console.WriteLine("Error Message : " +  err);});
               
            }

            Console.WriteLine("Any key to continue");
            Console.ReadKey();
        }

        
        /// <summary>
        /// This is the request that will carry our data and our results 
        /// Its the same as Exanmple two as well 
        /// </summary>
         
        // this says which widgets to use 
        [Belt(Step = OperationStep.Validation, Widget = typeof(ExampleThreeWidget_1))]
        [Belt(Step = OperationStep.Operation, Widget = typeof(ExampleThreeWidget_2))]
        class ExampleThreeRequest : Konveyer.Core.Interfaces.IRequest
        {
            // these are inputs (name) and outputs (Greeting)
            public string Name { get; set; }
            public string Greeting { get; set; }

            #region Konveyer.Core.Interfaces.IRequest Stuff (dont worry for now)
            public OperationStep CurrentStep { get; set; }
            public Exception Exception { get; set; } 
            #endregion
        }

        /// <summary>
        /// This can do the validation, we can use any widget, but we have a helper to 
        /// derive from 
        /// </summary>
        class ExampleThreeWidget_1 : ValidationWidget<ExampleThreeRequest>
        {

            public ExampleThreeWidget_1()
            {
                // in line rule 
                AddRule((request) =>
                {
                    var rtn = String.Empty;
                    if (request.Name != "Mike")
                    {
                        rtn = "We only greet Mike"; 
                    }

                    return rtn;
                });

                // rule as a method 
                AddRule(CheckName);

            }

            /// <summary>
            /// Check name using a method
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            public string CheckName(ExampleThreeRequest request)
            {
                var rtn = String.Empty;
                if (request.Name != "Mike")
                {
                    rtn = "We still only greet Mike";
                }

                return rtn;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        class ExampleThreeWidget_2 : TypedWidget<ExampleThreeRequest>
        {
            protected override void Do(ExampleThreeRequest request)
            {
                request.Greeting = "Hello " + request.Name;                              
            }
        }
    
    }
}
